package com.lse_api.control;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lse_api.config.interceptor.CrossInterceptorConfig;
import com.lse_api.config.multipledatasources.DataSourceContextHolder;
import com.lse_api.config.multipledatasources.aspect.DataSource;
import com.lse_api.entity.*;
import com.lse_api.exception.LseException;
import com.lse_api.service.*;
import com.lse_api.utils.*;
import com.lse_api.utils.encryption.AESEncryption;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户 前端控制器
 * </p>
 *
 * @author 祁雪
 * @since 2020-01-25
 */
@Slf4j
@Controller
@RequestMapping("/lseapi/users")
public class UsersController extends LseException implements ReturnMsg {

    @Autowired
    private UsersService usersService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private GroupListService groupListService;

    @Autowired
    private GroupUserService groupUserService;

    @Autowired
    private HttpServletRequest request;

    @Value("${com.lse.email.regex}")
    private String emailRegex;

    /**
     * 登录
     *
     * @param users
     * @return
     */
    @RequestMapping(value = "/login")
    @ResponseBody
    @DataSource("dataSource_lse")
    public Status login(Users users) {
        DataSourceContextHolder.setDB("dataSource_lse");

        if (StringUtils.isEmpty(users.getAccount())) {
            return Status.error(USER_ACCOUNT_IS_NULL);
        }

        if (StringUtils.isEmpty(users.getPass())) {
            return Status.error(USER_PASS_IS_NULL);
        }

        String pass = AESEncryption.Ecodes(users.getPass(), users.getAccount());

        QueryWrapper<Users> usersQueryWrapper = new QueryWrapper<>();
        usersQueryWrapper.eq("account", users.getAccount());
        usersQueryWrapper.eq("pass", pass);

        Users checkUser = usersService.getOne(usersQueryWrapper);

        if (checkUser == null) {
            return Status.error(USER_LOGIN_FAILURE);
        }

        if (checkUser.getIsSeal() > 0) {

            // 判断是否结束了封禁日期
            if (System.currentTimeMillis() > checkUser.getSealEndTime().getTime()) {
                // 修改用户封禁信息
                checkUser.setIsSeal(0);
                checkUser.setSealStartTime(null);
                checkUser.setSealEndTime(null);
                usersService.updateById(checkUser);

                return Status.success(loginFun(checkUser));
            }

            Map<String, Date> map = new HashMap<>();
            map.put("start", checkUser.getSealStartTime());
            map.put("end", checkUser.getSealEndTime());

            return Status.error(USER_SEAL, map);
        }

        return Status.success(loginFun(checkUser));

    }

    /**
     * 注册
     *
     * @param users
     * @return
     */
    @RequestMapping(value = "/reg")
    @ResponseBody
    @DataSource("dataSource_lse")
    public Status reg(Users users) {
        DataSourceContextHolder.setDB("dataSource_lse");
        if (StringUtils.isEmpty(users.getAccount())) {
            return Status.error(USER_ACCOUNT_IS_NULL);
        }

        if (StringUtils.isEmpty(users.getPass())) {
            return Status.error(USER_PASS_IS_NULL);
        }

        if (StringUtils.isEmpty(users.getEmail())) {
            return Status.error(USER_EMAIL_IS_NULL);
        }

        if (!users.getEmail().matches(emailRegex)) {
            return Status.error(USER_EMAIL_REGEX);
        }

        // 查询是否存在此账号
        QueryWrapper<Users> usersQueryWrapper = new QueryWrapper<>();
        usersQueryWrapper.eq("account", users.getAccount());
        int count = usersService.count(usersQueryWrapper);

        if (count > 0) {
            return Status.error(USER_REG_COUNT);
        }

        String pass = users.getPass();

        String usersUid = UUID.getUUIDToStr();

        users.setPass(AESEncryption.Ecodes(users.getPass(), users.getAccount()));
        users.setIsSeal(0);
        users.setRegTime(new Date());
        users.setSealEndTime(null);
        users.setSealStartTime(null);
        users.setUid(usersUid);
        users.setRegAddress(2);

        // 设置用户个性化信息
        UserInfo userInfo = new UserInfo();
        userInfo.setNickname(ChineseNameUtil.getChineseName());
        userInfo.setUid(UUID.getUUIDToStr());
        userInfo.setUsersUid(usersUid);

        // 存储用户
        usersService.save(users);
        DataSourceContextHolder.setDB(DataSourceContextHolder.DEFAULT_DS);
        userInfoService.save(userInfo);

        // 自动登录
        users.setPass(pass);
        Status status = login(users);

        return status;
    }

    /**
     * 查询封禁信息
     *
     * @return
     */
    @RequestMapping(value = "/getSealInfo")
    @ResponseBody
    @DataSource("dataSource_lse")
    public Status getSealInfo() {

        DataSourceContextHolder.setDB("dataSource_lse");
        String account = request.getParameter("account");

        if (StringUtils.isEmpty(account)) {
            return Status.error(USER_ACCOUNT_IS_NULL);
        }

        QueryWrapper<Users> usersQueryWrapper = new QueryWrapper<>();
        usersQueryWrapper.eq("account", account)
                .gt("is_seal", 0);

        Users users = usersService.getOne(usersQueryWrapper);

        if (users == null) {
            return Status.error(USER_SELECT_NULL);
        }

        Map<String, Date> map = new HashMap<>();
        map.put("start", users.getSealStartTime());
        map.put("end", users.getSealEndTime());

        // 判断是否结束了封禁日期
        if (System.currentTimeMillis() > users.getSealEndTime().getTime()) {

            return Status.success(USER_SEAL_TIME_END, map);
        }

        return Status.success(USER_SEAL, map);
    }

    /**
     * 随机获取一个名称
     *
     * @return
     */
    @RequestMapping(value = "/getOneName")
    @ResponseBody
    public Status getOneName() {
        return Status.success("get success", ChineseNameUtil.getChineseName());
    }

    /**
     * 读取项目组外链的信息
     * key: 加密密钥 解密得到此格式=> 项目组ID_用户ID(邀请者)
     *
     * @return
     */
    @RequestMapping(value = "/getGroupJoinData")
    @ResponseBody
    public Status getGroupJoinData() {

        String keyData = request.getParameter("key");

        if (StringUtils.isEmpty(keyData)) {
            return Status.error(API_GROUP_FIND_ID);
        }

        try {

            String data = AESEncryption.Dcodes(keyData, "LSE" + DateUtil.getOneDateTime(new Date(), "yyyy-MM-dd HH"));

            String[] datas = data.split("_");

            // 读取项目组信息以及项目组成员

            // 项目组信息
            GroupList groups = groupListService.getById(datas[0]);

            if (groups == null) {
                return Status.error(API_GROUP_NULL);
            }

            // 邀请者信息
            QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<>();
            userInfoQueryWrapper.eq("users_uid", datas[1]);
            UserInfo userInfo = userInfoService.getOne(userInfoQueryWrapper);

            // 项目组成员
            List<GroupUser> groupUserList = groupUserService.getUserListByGroup(datas[0]);

            Map<String, Object> map = new HashMap<>();
            map.put("group", groups);
            map.put("users", groupUserList);
            map.put("inviter", userInfo);

            return Status.success(map);
        } catch (Exception e) {
            log.error("the key decode out error", e);
            return Status.error(KEY_ERROR);
        }

    }

    /**
     * 登录通用返回读取
     *
     * @param checkUser
     * @return
     */
    public Map<String, Object> loginFun(Users checkUser) {
        DataSourceContextHolder.setDB(DataSourceContextHolder.DEFAULT_DS);
        // 登录成功返回用户信息
        QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<>();
        userInfoQueryWrapper.eq("users_uid", checkUser.getUid());

        UserInfo userInfo = userInfoService.getOne(userInfoQueryWrapper);

        // 用户信息为空则根据注册地址读取用户信息并写入到此库中
        if (userInfo == null) {
            String dataBase = UserInfoCheck.checkAddress(checkUser.getRegAddress());

            userInfo = userInfoService.getUserInfoByUserId(dataBase, checkUser.getUid());

            if (userInfo != null) {
                userInfoService.saveOrUpdate(userInfo);
            }
        }
        // 写入token
        Token token = new Token();
        token.setUid(checkUser.getUid());
        token.setUsersUid(checkUser.getUid());
        token.setInfo(AESEncryption.Ecodes(checkUser.getUid() + checkUser.getAccount() + System.currentTimeMillis(), checkUser.getAccount()));
        token.setTokenTime(new Date());
        token.setTokenIp(CrossInterceptorConfig.getIpAddr(request));

        tokenService.saveOrUpdate(token);

        Map<String, Object> map = new HashMap<>();
        map.put("userInfo", userInfo);
        map.put("token", token);

        return map;
    }
}

